
import 'package:dio/dio.dart';
import 'package:ycbl/net/http/header_interceptor.dart';

import '../../config/bl_constant.dart';
import 'package:ycbl/net/http/bl_request_method.dart';
import 'package:ycbl/model/bl_error_entity.dart';

import '../../utils/log_util.dart';


/// 对网络请求框架 Dio 的封装，
/// 关于 Dio 的使用：https://github.com/flutterchina/dio/blob/master/README-ZH.md
class BLRequestManager {

  Dio dio;

  /// 单例模式
  factory BLRequestManager.getInstance() => _instance;
  static BLRequestManager _instance = BLRequestManager._();

  BLRequestManager._(){
    if (dio == null) {
      BaseOptions options = BaseOptions(
        baseUrl: BLConstant.BASE_API_URL,
        connectTimeout: 30 * 1000,
        receiveTimeout: 30 * 1000,
      );
      dio = Dio(options);
      //添加拦截器
      dio.interceptors..add(LogInterceptor(responseBody: false));
      dio.interceptors..add(HeaderInterceptor());
    }
  }

  /// 使用 Get 请求
  get(String path, {data, Map<String, dynamic> queryParameters, Options options,
    Function(dynamic) onSuccess, Function(BLErrorEntity) onError,}) {
    request(
      path,
      method: BLRequestMethod.GET,
      data: data,
      queryParameters: queryParameters,
      options: options,
      onSuccess: onSuccess,
      onError: onError,
    );
  }

  /// 使用 Post 请求
  post(String path, {data, Map<String, dynamic> queryParameters, Options options,
    Function(dynamic) onSuccess, Function(BLErrorEntity) onError,}) {
    request(
      path,
      method: BLRequestMethod.POST,
      data: data,
      queryParameters: queryParameters,
      options: options,
      onSuccess: onSuccess,
      onError: onError,
    );
  }

  /// 使用 Delete 请求
  delete(String path, {data, Map<String, dynamic> queryParameters, Options options,
    Function(dynamic) onSuccess, Function(BLErrorEntity) onError,}) {
    request(
      path,
      method: BLRequestMethod.DELETE,
      data: data,
      queryParameters: queryParameters,
      options: options,
      onSuccess: onSuccess,
      onError: onError,
    );
  }

  /// 发起请求
  request(String path, {BLRequestMethod method, data, Map<String, dynamic> queryParameters,
    Options options, Function(dynamic) onSuccess, Function(BLErrorEntity) onError,}) async{
    try {
      //发起请求 获取响应
      Response response = await dio.request(
        path,
        data: data,
        queryParameters: queryParameters,
        options: checkOptions(method, options),
      );
      // 处理响应
      if (response != null && response.statusCode == 200 && response.data != null) {
        if(onSuccess != null) {
          onSuccess(response.data);
        }
      }else {
        if(onError != null) {
          onError(BLErrorEntity(code: response?.statusCode ?? -200, message: "未知错误"));
        }
      }
    }on DioError catch(e) {
      if(onError != null) {
        onError(createBLErrorEntity(e));
      }
    } catch (e) {
      onError(BLErrorEntity(code: -400, message: e?.toString() ?? "未知错误"));
    }
  }

  /// 设置请求方式
  Options checkOptions(BLRequestMethod method, options) {

    options ??= Options();
    if(method != null ) {
      options.method = method.name;
    }
    return options;
  }

  /// 错误信息
  BLErrorEntity createBLErrorEntity(DioError error) {
    LogUtil.d('dioError: $error');
    switch (error.type) {
      case DioErrorType.CANCEL:{
        return BLErrorEntity(code: -1, message: "请求取消");
      }
      break;
      case DioErrorType.CONNECT_TIMEOUT:{
        return BLErrorEntity(code: -2, message: "连接超时");
      }
      break;
      case DioErrorType.SEND_TIMEOUT:{
        return BLErrorEntity(code: -3, message: "请求超时");
      }
      break;
      case DioErrorType.RECEIVE_TIMEOUT:{
        return BLErrorEntity(code: -4, message: "响应超时");
      }
      break;
      case DioErrorType.RESPONSE:{
        try {
          int errCode = error.response.statusCode;
          String errMsg = error.response.statusMessage;
          return BLErrorEntity(code: errCode, message: errMsg);
//          switch (errCode) {
//            case 400: {
//              return BLErrorEntity(code: errCode, message: "请求语法错误");
//            }
//            break;
//            case 403: {
//              return BLErrorEntity(code: errCode, message: "服务器拒绝执行");
//            }
//            break;
//            case 404: {
//              return BLErrorEntity(code: errCode, message: "无法连接服务器");
//            }
//            break;
//            case 405: {
//              return BLErrorEntity(code: errCode, message: "请求方法被禁止");
//            }
//            break;
//            case 500: {
//              return BLErrorEntity(code: errCode, message: "服务器内部错误");
//            }
//            break;
//            case 502: {
//              return BLErrorEntity(code: errCode, message: "无效的请求");
//            }
//            break;
//            case 503: {
//              return BLErrorEntity(code: errCode, message: "服务器挂了");
//            }
//            break;
//            case 505: {
//              return BLErrorEntity(code: errCode, message: "不支持HTTP协议请求");
//            }
//            break;
//            default: {
//              return BLErrorEntity(code: errCode, message: "未知错误");
//            }
//          }
        } on Exception catch(_) {
          return BLErrorEntity(code: -5, message: "未知错误");
        }
      }
      break;
      default: {
        return BLErrorEntity(code: -6, message: error.message);
      }
    }
  }

}